package com.wondersgroup.core.service;

import java.io.File;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.github.pagehelper.PageHelper;
import com.wondersgroup.core.frame.TraceException;
import com.wondersgroup.core.mapper.AttachmentMapper;
import com.wondersgroup.core.mapper.TraceHistoryMapper;
import com.wondersgroup.core.model.Attachment;
import com.wondersgroup.core.model.TraceHistory;
import com.wondersgroup.core.util.ErrorMessageConstant;
import com.wondersgroup.core.util.FileUploadUtils;

@Service
public class UtilService  {

    @Autowired
	private AttachmentMapper attachmentMapper;
    
    @Autowired
    private TraceHistoryMapper traceHistoryMapper;
    
    
    public void insertTraceHistory(String barcode, Integer barcodeType, String batchId, Integer clientAppType, String clientAppVersion, String clientDeviceSn, String functionName, String initialRequest, Integer productType, String requestName, String serverHostName, String serverIpAddress, String gisLatitude, String gisLongitude, Integer platformId, Integer isPlatformResponse) {
    	TraceHistory history = new TraceHistory();
    	history.setBarcode(barcode);
    	history.setBarcodeType(barcodeType);
    	history.setBatchId(batchId);
    	history.setClientAppType(clientAppType);
    	history.setClientAppVersion(clientAppVersion);
    	history.setClientDeviceSn(clientDeviceSn);
    	history.setCreateDate(new Date());
    	history.setFunctionName(functionName);
    	history.setInitialRequest(initialRequest);
    	history.setProductType(productType);
    	history.setRequestName(requestName);
    	history.setServerHostName(serverHostName);
    	history.setServerIpAddress(serverIpAddress);
    	history.setGisLatitude(gisLatitude);
    	history.setGisLongitude(gisLongitude);
    	history.setPlatformId(platformId);
    	history.setIsPlatformResponse(isPlatformResponse);
		traceHistoryMapper.insert(history);
    }
    

	/**
	 * 【×】查看附件列表</br>
	 */
	public List<Attachment> queryAttFile(Attachment attachment){
		return attachmentMapper.select(attachment);
	}

	/**
	 * 【×】删除某个对象列席以及某个对象编号对应的所有附件</br>
	 * 如：要删除某个供应商对应的某个资质中的所有资质文件</br>
	 * 1，物理删除附件表对应的记录</br> 
	 * 2，物理删除附件表中每条记录对应的远程文件</br>
	 * @param attObjectType 附件对象类型
	 * @param attObjectId 附件对象编号
	 * @throws TraceException
	 */
	@Transactional(readOnly = false)
	public void deleteAllAttFiles(String attObjectType, int attObjectId)
			throws TraceException {
		// step 1: 判断参数
		if (StringUtils.isEmpty(attObjectType)) {
			throw TraceException.returnException("000015");
		}
		if (attObjectId < 0) {
			throw TraceException.returnException("000016");
		}
		Attachment att = new Attachment();
		att.setObjId(attObjectId);
		att.setObjType(attObjectType);
		
		List<Attachment> attList = attachmentMapper.select(att);
		// 如果没有找到附件，直接返回
		if (null == attList || attList.size() < 1) {
			return;
		}
		// 对于每个附件对象
		for (Attachment a : attList) {
	        if(FileUploadUtils.deleteFileOnRemote(a.getFilePath())){
	        	attachmentMapper.delete(a);
	        }else{
	            throw TraceException.returnException("000017");
	        }
		}
	}

	/**
	 * 【×】删除某个对象列席以及某个对象编号对应的某些附件</br> 
	 * 如：要删除某个供应商对应的某个资质中的某些资质文件</br>
	 * 1，物理删除附件表对应的记录</br> 
	 * 2，物理删除附件表中每条记录对应的远程文件</br>
	 * @param attIdList 附件编号列表
	 * @throws TraceException
	 */
	@Transactional(readOnly = false)
	public void deleteAttFiles(List<Integer> attIdList) throws TraceException {
		// step 1: 判断参数
		if (null == attIdList || attIdList.size() < 1) {
			return;
		}
		for (Integer pk : attIdList) {
			// step2: 找到对应的附件对象
			Attachment a = attachmentMapper.selectByPrimaryKey(pk);
			if (null == a) {
				throw TraceException.returnException("000018");
			}
			if(FileUploadUtils.deleteFileOnRemote(a.getFilePath())){
	        	attachmentMapper.delete(a);
	        }else{
	            throw TraceException.returnException("000017");
	        }
		}
	}

	/**
	 * 【×】上传某个对象列席以及某个对象编号对应的某个附件</br> 
	 * 如：要上传某个供应商对应的某个资质中的某个资质文件</br>
	 * 1，关于文件路径：每个不同的attObjectType对应不同的远程路径(需要从配置文件中读取)</br>
	 * 2，关于文件路径：每个附件文件的文件名为一个UUID，UUID的生成请参考开源类库</br>
	 * 关于文件路径：如：供应商资质对应的路径为：...\supplierquali\,
	 * 那么该附件文件路径就为：...\supplierquali\UUID.后缀, 这样可以确保文件名的唯一性
	 * @param attObjectType 附件对象类型
	 * @param attObjectId 附件对象编号
	 * @param attName 附件名称
	 * @param attDesc 附件描述
	 * @param uploadDate 上传时间
	 * @param file 文件
	 * @throws TraceException
	 * @throws  
	 */
	@Transactional(readOnly = false)
	public Attachment uploadAttFile(Integer companyId, String attObjectType, int attObjectId,
			String attName, String attDesc, Date uploadDate, MultipartFile file)
			throws TraceException {
		// step 1: 判断参数
		if (null == file || file.getSize() <= 0) {
			throw TraceException.returnException("000019");
		}
		if (StringUtils.isEmpty(attObjectType)) {
			throw TraceException.returnException("000015");
		}
		if (attObjectId < 0) {
			throw TraceException.returnException("000016");
		}
		
		String toFileName = FileUploadUtils.getFileName(file.getOriginalFilename());

		String upload = FileUploadUtils.contextPath + FileUploadUtils.upload;
		
		String path = upload + "/" + attObjectType;
		File file1 = new File(path);
		if (!file1.exists()){
			file1.mkdirs();
		}
			
		String toFile = path + "/" + toFileName;
		Attachment a = null;
        String remotePath = FileUploadUtils.uploadFileToRemote(file, toFileName, attObjectType, toFile);
		if (remotePath!=null && !remotePath.isEmpty()) {
			a = new Attachment();
			a.setObjId(attObjectId);
			a.setObjType(attObjectType);
			a.setDescription(attDesc);
			a.setName(attName);
		
			a.setFilePath(remotePath);
			a.setCreateDate(uploadDate);
			a.setLastModifiedDate(uploadDate);
			attachmentMapper.insert(a);
		} else {
			throw TraceException.returnException("000020");
		}
		return a;
	}
	
	/**
	 * 上传本地文件</br> 
	 * @param attObjectType 附件对象类型
	 * @param attObjectId 附件对象编号
	 * @param attName 附件名称
	 * @param attDesc 附件描述
	 * @param uploadDate 上传时间
	 * @param file 文件
	 * @throws TraceException
	 * @throws  
	 */
	@Transactional(readOnly = false)
	public Attachment uploadLocalAttFile(Integer companyId, String attObjectType, int attObjectId,
			String attName, String attDesc, Date uploadDate, File file)
			throws TraceException {
		// step 1: 判断参数
		if (StringUtils.isEmpty(attObjectType)) {
			throw TraceException.returnException("000015");
		}
		if (attObjectId < 0) {
			throw TraceException.returnException("000016");
		}
		Attachment a = null;
		String remotePath = FileUploadUtils.uploadLocalFileToRemote(file, attObjectType);
		if (remotePath!=null && !remotePath.isEmpty()) {
			a = new Attachment();
			a.setObjId(attObjectId);
			a.setObjType(attObjectType);
			a.setDescription(attDesc);
			a.setName(attName);
			a.setFilePath(remotePath);
			a.setCreateDate(uploadDate);
			attachmentMapper.insert(a);
		} else {
			throw TraceException.returnException("000020");
		}
		return a;
	}
	
	/**
	 * 更新附件
	 * 更新附件标题，附件描述，附件文件
	 * @param attId
	 * @param attName
	 * @param attDesc
	 * @param uploadDate
	 * @param file
	 * @return
	 * @throws TraceException
	 */
	public Attachment updateAttFile(Integer attId, String attName, String attDesc, Date uploadDate, MultipartFile file) throws TraceException{
		//step 1: 参数验证
		if(null == attId){
			throw TraceException.returnException("000016");
		}
		
		//step 2: 加载附件对象
		Attachment a = attachmentMapper.selectByPrimaryKey(attId);
		if(null == a){
			throw TraceException.returnException("000018");
		}
		
		//step 3: 如果更新文件，先删除文件
		if (null != file && file.getSize() > 0) {
			if (FileUploadUtils.deleteFileOnRemote(a.getFilePath())) {
				// step 4: 文件不存，或者文件删除成功, 继续更新文件
				String toFileName = FileUploadUtils.getFileName(file.getOriginalFilename());

				String upload = FileUploadUtils.contextPath + FileUploadUtils.upload;
				
				String path = upload + "/" + a.getObjType();
				File file1 = new File(path);
				if (!file1.exists()){
					file1.mkdirs();
				}
					
				String toFile = path + "/" + toFileName;
                String remotePath = FileUploadUtils.uploadFileToRemote(file, toFileName, a.getObjType(), toFile);
				
				if (remotePath!=null && !remotePath.isEmpty()) {
					a.setDescription(attDesc);
					a.setName(attName);
					
                    a.setFilePath(remotePath);
					a.setCreateDate(uploadDate);
					attachmentMapper.updateByPrimaryKey(a);
				} else {
					throw TraceException.returnException("000020");
				}
			} else {
				// 如果已经存在的文件删除失败，抛exception
				throw TraceException.returnException("000017");
			}
		}else{
			//step 5:如果不更新附件, 仅仅更新文件标题，文件描述
			a.setDescription(attDesc);
			a.setName(attName);
			attachmentMapper.updateByPrimaryKey(a);
		}
		return a;
	}
	/**
	 * 【×】查看附件列表</br>
	 * @throws TraceException
	 */
	public List<Attachment> queryAttFile(Attachment attachment,int pageNum,int pageSize)
			throws TraceException {
		PageHelper.startPage(pageNum, pageSize);
		return attachmentMapper.select(attachment);
	}
	
	public Attachment getAttachment(int attachmentId){
		return attachmentMapper.selectByPrimaryKey(attachmentId);
	}
	
	public void createAttachment(Attachment attachment){
		if(attachment==null){
			throw TraceException.returnException(ErrorMessageConstant.CODE_PARAM_ERROR);
		}
		attachmentMapper.insert(attachment);
	}
	
	public void updateAttachment(Attachment attachment){
		if (attachment == null) {
			throw TraceException.returnException(ErrorMessageConstant.CODE_PARAM_ERROR);
		} 
		attachmentMapper.updateByPrimaryKey(attachment);
	}
	
}
